use crate::types::{Method, Protocol};

pub trait ServerDef {
    fn server_name() -> &'static str;

    fn route_path(
        current: Option<&str>,
        parent: Option<&str>,
        ident: &str,
        mod_path: &str,
    ) -> String {
        if let Some(current) = current {
            return current.to_string();
        }
        let parent = match parent {
            Some(parent) => parent.to_string(),
            None => {
                let segments = mod_path.split("::").skip(1).collect::<Vec<&str>>();
                let mut parent = segments.join("/");
                parent.insert(0, '/');
                parent
            }
        };
        if ident.starts_with("_") {
            return parent.to_string();
        }
        format!("{}/{}", parent, ident)
    }
}

pub struct HttpProtocol;

pub struct SseProtocol;

pub struct WsProtocol;

impl From<HttpProtocol> for Protocol {
    fn from(_: HttpProtocol) -> Self {
        Self::Http
    }
}

impl From<SseProtocol> for Protocol {
    fn from(_: SseProtocol) -> Self {
        Self::Sse
    }
}

impl From<WsProtocol> for Protocol {
    fn from(_: WsProtocol) -> Self {
        Self::Ws
    }
}

pub trait HandlerDef {
    type Input;
    type Output;
    type Protocol;

    fn method() -> Method;

    fn protocol() -> Protocol;

    fn path() -> &'static str;
}
